#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2024-9-11 0:10:58
# @Author  : mage
# @Link    : http://fengmm521.taobao.com
from machine import Pin,UART,Timer
import time
import network
import time
import math
import uartUtil
import touchTool
import urandom
import json
#

uart1 = UART(2, baudrate=115200, tx=16, rx=17,timeout=10)


blePoints = {}

Q1 = 0
Q2 = 0
Q3 = 0
Q4 = 0
QST = 0

pin12 = None
pin19 = None
pin32 = None


devname = 'fengmm521'   #未定义时的默认蓝牙名称

#文件是否存在
def isExists(pth):
    try:
        f = open(pth,'rb')
        f.close()
        return True
    except Exception:
        return False

#随机一个整数
def randint(min, max):
    span = max - min + 1
    div = 0x3fffffff // span
    offset = urandom.getrandbits(30) // div
    val = min + offset
    return val

def handle_interrupt(pin):
    print("is Demf msg:", pin.value())
    dtmfState()

#初始化dtmf引脚为输入
def initDtmfPin():
    global Q1, Q2, Q3, Q4,QST
    Q1 = Pin(33, Pin.IN)     # 输入引脚
    Q2 = Pin(26, Pin.IN)     # 输入引脚
    Q3 = Pin(25, Pin.IN)     # 输入引脚
    Q4 = Pin(35, Pin.IN)     # 输入引脚
    QST = Pin(14, Pin.IN)     # 输入引脚
    # 配置中断，触发条件为下降沿（Pin.IRQ_FALLING），并绑定回调函数
    QST.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)

#初始化点击头状态
def initTouch():
    global pin12, pin19, pin32
    pin12 = Pin(12, Pin.OUT)    # 输出引脚
    pin19 = Pin(19, Pin.OUT)    # 输出引脚
    pin32 = Pin(32, Pin.OUT)    # 输出引脚
    pin12.value(0)              # 设置输出引脚为低电平
    pin19.value(0)              # 设置输出引脚为低电平
    pin32.value(0)              # 设置输出引脚为低电平

#直接发送数据给4G模块
def send_cmd(command):
    print(command)
    cmd = command + '\r\n'
    uart1.write(cmd)

#ping设备连接状态
def ping():
    send_cmd('AT')

#播打一个电话号码
def callPhone(phnum = 13590289064):
    print('zzzzzzzzz')
    if type(phnum) == int:
        phnum = str(phnum)
    if len(phnum) != 11:
        print('phone number erro, number len is not 11')
        return
    cmd = 'ATD%s;'%(phnum)
    send_cmd(cmd)

#挂断电话
def offCall(isAll = True):
    if isAll:
        send_cmd('AT+CHUP')
    else:
        send_cmd('ATH')
#接电话
def tackOn():
    send_cmd('ATA')


#查询信号强度
def showSignal():
    send_cmd('AT+CSQ')

#检测SIM卡是否插入
def cardState():
    send_cmd('AT+CPIN?')

#查询网络状态
def netState():
    send_cmd('AT+CREG?')  #网络注册状态
    time.sleep(1)
    send_cmd('AT+CGATT?') #网络附着状态

# 设置4G模块音频音量
def setVolume(v):
    send_cmd('AT+MAUDPLCFG="volume",%d'%(v))

#初始化音频音量
def initVolume():
    setVolume(70)

def ringCmd():
    print('run ringCmd')
#控制点击头
def touchPin(p):
    p = int(p)
    print('touchPin',p)
    if p == 1:
        pin12.value(1)
        time.sleep_ms(100)
        pin12.value(0)
    elif p == 2:
        print('in 2')
        pin19.value(1)
        time.sleep_ms(100)
        pin19.value(0)
    elif p == 3:
        pin32.value(1)
        time.sleep_ms(100)
        pin32.value(0)

#运行蓝牙指令
def bleTouch(p):
    print('bleTouch',p)
    pt = blePoints[p]
    touchTool.moveTo(pt[0],pt[1],True)
    dttmp = randint(50,120)
    time.sleep_ms(dttmp)
    touchTool.moveTo(pt[0],pt[1],False)


isRingAutoOn = False            #是否自动接听来电
ringTime = 6                    #自动接听来电等待时间,当响铃时间大于这个秒数时自动接听
tackOnPhoneNum = []  #只有当来电号码等于这个号码时才会自动接听和处理铃声计数的相应操作
isPhoneNum = False              #是否检测来电号码
isCallIn = False                #是否有来电
isUseBle = False                #是否使用蓝牙控制  useBle=0-不使用蓝牙/useBle=1-使用蓝牙
timOBJ = Timer(-1)              #建一个虚拟定时器,来于处理电话已响铃时长判断
isAutoAnswered = False          #是否已经自动接听电话
ringCount = 0

#定时器结束调用函数
def onTimerEnd(tim):
    global isCallIn,ringCount,isPhoneNum,isAutoAnswered
    # if isCallIn:
    if isCallIn:
        tackOn()  #自动接听电话
        print('---timer-tackOn---')
    tim.deinit()

# ,"17189211935",
# 解析接收到的数据
def defineReceive(line):
    global isCallIn,ringCount,isPhoneNum,isAutoAnswered
    line = line.decode().strip()
    print('line->',line)
    if len(tackOnPhoneNum) > 0:
        for i,v in enumerate(tackOnPhoneNum):
            if len(v) <6 or v in line:
                isPhoneNum = True
    else:
        isPhoneNum = True
    
    if "RING" in line:  # 检测到来电
        print("Incoming call detected=1")
        isCallIn = True
        ringCount += 1
    # if isPhoneNum and isCallIn:        #如果来电号码等于tackOnPhoneNum并且有来电
    if isPhoneNum and isCallIn and not isAutoAnswered:        #如果来电号码等于tackOnPhoneNum并且有来电
        isAutoAnswered = True      #电话已自动接听
        if isRingAutoOn:               #自动接听电话开启就自动接听,然后使用DTMF指令控制 
            tackOn()                   # 自动接听电话
            isCallIn = True
        else:
            #启动定时器来判断响铃时间
            timOBJ.init(period=ringTime*1000,mode=Timer.ONE_SHOT ,callback=onTimerEnd)
            print('clock!!!!!!')
    elif isCallIn and not isPhoneNum and ringCount >= 2: #有电话打入,但没有对应电话号吗,铃声响了2次以上,直接挂断电话
        isCallIn = False
        ringCount = 0
        isPhoneNum = False
        offCall()  #挂断电话 
    if "NO CARRIER" in line:  # 检测到挂断电话
        print("Call ended")
        isCallIn = False
        ringCount = 0
        isAutoAnswered = False    #重置变量，允许下次来电时自动接听
        if isPhoneNum: #号码匹配
            ringCmd() #执行来电运行指令
        isPhoneNum = False

#DTMF检测
touchState = 0  # 0:表示当前工作在物理点击状态下,即按一下*号键会切换到这个状态下, 1:表示当前工作在蓝牙点击状态下,按一下#号会切换到这个状态下

def dtmfState():
    global touchState
    outst = 0
    # 获取引脚状态
    Q1_state = Q1.value()  # 0表示低电平，1表示高电平
    Q2_state = Q2.value()  # 0表示低电平，1表示高电平
    Q3_state = Q3.value()  # 0表示低电平，1表示高电平
    Q4_state = Q4.value()  # 0表示低电平，1表示高电平

    #1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,0:10,*:11,#:12
    outst = Q4_state*8 + Q3_state*4 + Q2_state*2 + Q1_state
    if touchState == 0:#当前工作在物理点击状态下
        if outst > 0 and outst <= 3:
            touchPin(outst)
        elif outst == 11: #当前在物理点击头状态下,*号被按下,
            print("*,down")
        elif outst == 12: #当前在物理点击头状态下,#号被按下,切换为蓝牙点击模式
            print("#,down")
            if isUseBle:
                touchState = 1
    elif touchState == 1:
        if outst != 11: #当前在蓝牙点击头状态下
            bleTouch(outst)
        else: #当前在蓝牙点击头状态下,*号被按下,切换为物理点击模式
            print("#,down")
            touchState = 0
    # # 等待1秒
    print(f"Q1: {Q1_state}, Q2: {Q2_state}, Q3: {Q3_state}, Q4: {Q4_state}")

#从文件读取设备蓝牙名
def initDeviceName():
    global devname
    if isExists('name.txt'):
        f = open('name.txt',"r")
        devname = f.read()
        f.close() 
#从文件读取设备配置文件,这里主要配置是否来电自动接听,配置是否启动蓝牙点击器,配置蓝牙点击器的点击坐标,响铃多少次接听,
#配置只检测已知来电号码
#配置是否微信推送消息
def configDevice():
    global blePoints,isRingAutoOn,tackOnPhoneNum,isUseBle
    if isExists('config.txt'):
        f = open('config.txt',"r")
        confdat = json.loads(f.read())
        f.close()
        blePoints = confdat['pt']                 #蓝牙点击DTMF坐标
        isRingAutoOn = confdat['auto']            #是否来电自动接听
        tackOnPhoneNum = confdat['phoneNum']      #是否只检测已知来电号码
        isUseBle = confdat['useBle']
#程序入口
if __name__=="__main__":
    # wifi_connect()
    initDtmfPin()
    initTouch()
    initDeviceName()
    print("device name:%s"%(devname))
    configDevice()
    uartUtil.start()
    if isUseBle:
        touchTool.set_screenWH(540,960)
        touchTool.start(devname)
    time.sleep(1)                    #等3秒,手动配对成功,这个时间根据不同手机决定
    print("start and connect")
    initVolume()                    #这里需要多发送几次设置音量,否则可能不生效
    time.sleep(1)
    initVolume()
    time.sleep(1)
    initVolume()
    time.sleep(1)
    isloopDtmf = True
    while True:
        dat = uartUtil.reciveDat()
        if dat:
            dat = dat.decode()
            print(dat)
            dat =dat.strip()
            print(type(dat))
            if dat.find(',') != -1:
                dats = dat.split(',')
                if dats[0] == '0':#0：给4G模块发着实指令，1:控制点击头,2：接电话后只做dtmf状态读取,3,播打电话
                    send_cmd(dats[1])
                elif dats[0] == '1': 
                    touchPin(int(dats[1]))
                elif dats[0] == '2': 
                    offCall()   #挂断电话
                elif dats[0] == '3': 
                    if len(dats[1]) == 11:
                        callPhone(dats[1])
                    else:
                        callPhone()
                elif dats[0] == '4': #控制物理点击器
                    if int(dats[1]) == 10:
                        print('10')
                        pin12.value(0)
                    elif int(dats[1]) == 11:
                        print('11')
                        pin12.value(1)
                    if int(dats[1]) == 20:
                        print('20')
                        pin19.value(0)
                    elif int(dats[1]) == 21:
                        print('21')
                        pin19.value(1)
                    if int(dats[1]) == 30:
                        print('30')
                        pin32.value(0)
                    elif int(dats[1]) == 31:
                        print('31')
                        pin32.value(1)
                elif dats[0] == '5':
                     sendstr = 'AT+MAUDPLCFG="volume",%s'%(dats[1])
                     send_cmd(sendstr)
            else:
                send_cmd(dat)
        line = uart1.readline()
        if line:
            defineReceive(line)
    